import json
import os

from django.conf import settings
from django.db.models import Q
from django.shortcuts import render
from django.utils import timezone
from django.views import View
from django.views.decorators.http import require_POST, require_GET

from shortuuid import uuid

from apps.app_focus.form import FocusForm
from apps.app_focus.models import Focus
from apps.app_friend.form import FriendForm
from apps.app_post.form import PostForm, CategoryForm, TagForm
from apps.app_post.models import Category, Post, Tag
from apps.app_post.serializers import CategorySerializer, TagsSerializer, PostsSerializer
from apps.app_talk.form import TalkForm
from apps.app_talk.models import Mood
from apps.app_talk.serializers import MoodsSerializer
from utils.resultful import ResultCode


def index(request):
    return render(request, 'cms/index.html')


@require_GET
def post_list(request):
    categories = CategorySerializer(Category.objects.all(), many=True)
    context = {
        "categories": categories.data,
    }
    return render(request, 'cms/post-list.html', context=context)


@require_POST
def change_recommend(request, ):
    is_recom = int(request.POST.get('is_recom', 0))
    pid = request.POST.get('pid')
    post = Post.objects.filter(pk=pid)
    if not post.exists():
        return ResultCode.params_error(msg="该文章已删除~~")
    post.update(is_recom=True if is_recom else False)
    return ResultCode.ok(msg="修改成功")


class PostEditView(View):
    def get(self, request, pid):
        categories = CategorySerializer(Category.objects.all(), many=True)
        tags = TagsSerializer(Tag.objects.all(), many=True)
        context = {
            "categories": categories.data,
            "tags": tags.data,
        }
        if pid:
            try:
                post = PostsSerializer(Post.objects.get(pk=pid))
                context['post'] = post.data
            except Post.DoesNotExist:
                return render(request, 'error.html', context={"msg": '该文章不存在~~, <a href="/cms/posts/">返回</a>'})
        return render(request, 'cms/post-edit.html', context=context)

    def post(self, request, pid):
        if pid:
            try:
                post = Post.objects.get(pk=pid)
            except:
                return ResultCode.params_error(msg='该文章不存在~~')
            form = PostForm(request.POST, instance=post)
        else:
            form = PostForm(request.POST)
        if form.is_valid():
            post = form.save(commit=False)
            post.author = request.user
            post.save()
            tags = request.POST.get('tags')
            if tags:
                tag_list = tags.split(',')
                add_list = []
                for tag in tag_list:
                    try:
                        add_list.append(Tag.objects.get(name=tag))
                    except Tag.DoesNotExist:
                        pass
                post.tags.set(add_list)
            post.save()
            return ResultCode.ok(msg='文章发布成功~~')
        else:
            return ResultCode.params_error(msg=form.get_once_errors())


class CategoryView(View):
    def get(self, request):
        return render(request, 'cms/category.html')

    def post(self, request):
        if not request.POST.get('name', ''):
            return ResultCode.params_error()
        form = CategoryForm(request.POST)
        if form.is_valid():
            form.save()
            return ResultCode.ok(msg='新增分类成功~~')
        else:
            return ResultCode.params_error(msg=form.get_once_errors())

    def put(self, request):
        if not request.body:
            return ResultCode.params_error()
        data = json.loads(request.body.decode())
        try:
            category = Category.objects.filter(Q(name=data['name']) & ~Q(pk=data['id']))
        except:
            return ResultCode.params_error()
        if not category.exists():
            Category.objects.filter(pk=data['id']).update(name=data['name'])
            return ResultCode.ok(msg='修改分类成功~~')
        else:
            return ResultCode.params_error(msg='该分类已存在, 请重新输入~~')


class TagView(View):
    def get(self, request):
        return render(request, 'cms/tags.html')

    def post(self, request):
        if not request.POST.get('name', ''):
            return ResultCode.params_error()
        form = TagForm(request.POST)
        if form.is_valid():
            form.save()
            return ResultCode.ok(msg='新增标签成功~~')
        else:
            return ResultCode.params_error(msg=form.get_once_errors())

    def put(self, request):
        if not request.body:
            return ResultCode.params_error()
        data = json.loads(request.body.decode())
        try:
            tag = Tag.objects.filter(Q(name=data['name']) & ~Q(pk=data['id']))
        except:
            return ResultCode.params_error()
        if not tag.exists():
            Tag.objects.filter(pk=data['id']).update(name=data['name'])
            return ResultCode.ok(msg='修改标签成功~~')
        else:
            return ResultCode.params_error(msg='该标签已存在, 请重新输入~~')


class FocusView(View):
    def get(self, request):
        focuses = Focus.objects.filter(end_time__gt=timezone.now()).order_by('priority')
        context = {
            "focuses": focuses
        }
        return render(request, 'cms/focus.html', context=context)

    def post(self, request):
        form = FocusForm(request.POST)
        if form.is_valid():
            form.save()
            return ResultCode.ok(msg='新增焦点图成功~~')
        else:
            return ResultCode.params_error(msg=form.get_once_errors())

    def put(self, request):
        if not request.body:
            return ResultCode.params_error()
        data = json.loads(request.body.decode())
        try:
            focus = Focus.objects.get(pk=data['pk'])
        except Focus.DoesNotExist:
            return ResultCode.params_error(msg='该焦点图不存在~~')
        form = FocusForm(data, instance=focus)
        if form.is_valid():
            form.save()
            return ResultCode.ok(msg='修改焦点图成功~~')
        else:
            return ResultCode.params_error(msg=form.get_once_errors())


@require_GET
def talk_list(request):
    moods = Mood.objects.all()
    context = {
        "moods": moods,
    }
    return render(request, 'cms/talk-list.html', context=context)


class TalkEditView(View):
    def get(self, request):
        moods = Mood.objects.all()
        context = {
            'moods': moods
        }
        return render(request, 'cms/talk-edit.html', context=context)

    def post(self, request):
        form = TalkForm(request.POST)
        if form.is_valid():
            form.save()
            return ResultCode.ok()
        else:
            return ResultCode.params_error(msg=form.get_once_errors())


class MoodView(View):
    def get(self, request):
        return render(request, 'cms/mood.html')

    def post(self, request):
        name = request.POST.get('name', '')
        if not name:
            return ResultCode.params_error()
        mood = Mood.objects.filter(name=name)
        if mood.exists():
            return ResultCode.params_error(msg='该心情已存在~~')
        Mood.objects.create(name=name)
        return ResultCode.ok()


class FriendsView(View):
    def get(self, request):
        return render(request, 'cms/friends.html')

    def post(self, request):
        form = FriendForm(request.POST)
        if form.is_valid():
            form.save()
            return ResultCode.ok()
        else:
            return ResultCode.params_error(msg=form.get_once_errors())


@require_POST
def upload(request):
    file = request.FILES.get('file')
    ext = file.name.split('.')[-1]
    name = uuid() + '.' + ext
    with open(os.path.join(settings.MEDIA_ROOT, name), 'wb') as f:
        for chunk in file.chunks():
            f.write(chunk)
    url = request.build_absolute_uri(settings.MEDIA_URL + name)
    # http://127.0.0.1/media/123456.png
    return ResultCode.ok(message="上传成功！", data={
        # "url": os.path.join(settings.MEDIA_URL, name),
        "url": url
    })
